package com.qf.service.impl;

import com.qf.config.IdWorker;
import com.qf.constant.CacheConstants;
import com.qf.constant.RabbitMQConstants;
import com.qf.constant.ReportStateConstants;
import com.qf.constant.SourceType;
import com.qf.enums.InterfaceExceptionEnums;
import com.qf.exception.SmsException;
import com.qf.form.SmsInterfaceForm;
import com.qf.model.StandardSubmit;
import com.qf.service.SmsInterfaceService;
import com.qf.service.api.CacheService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author 何星宇
 * @version V1.0
 * @Date 2021/11/22 14:29
 */

@Service
@Slf4j
public class SmsInterfaceServiceImpl implements SmsInterfaceService {

    @Autowired
    private CacheService cacheService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IdWorker idWorkerNum;

    /**
     * 校验下行接口参数，并在校验成功后，将消息发送到RabbitMQ中
     * @param smsInterfaceForm
     */
    @Override
    public void checkParameters(SmsInterfaceForm smsInterfaceForm) {


        //-----------------------------------1.校验ClientID-----------------------------------
        //根据用户传递过来的ClientID，去缓存模块查询客户信息
        String clientID = smsInterfaceForm.getClientID();
        Map map = cacheService.hMGet(CacheConstants.CACHE_PREFIX_CLIENT + clientID);
        //判断map是否为空
        if (map==null||map.size()==0){
            //根据ClientID什么都没查询到
            //记录日志
            log.info("【接口模块】 认证错误：clientId错误  ClientID={}",clientID);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_CLIENT_ID_ERROR);
        }



        //-----------------------------------2.校验密码-----------------------------------
        String pwd = smsInterfaceForm.getPwd();
        if (StringUtils.isEmpty(pwd)|| !DigestUtils.md5Hex(pwd).toUpperCase().equals(map.get("pwd"))){
            //没有传递密码或密码错误
            //记录日志
            log.info("【接口模块】 密码错误。  pwd={}",pwd);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_PWD_ERROR);
        }



        //-----------------------------------3.校验IP地址-----------------------------------
        String userIp = smsInterfaceForm.getIp();
        //校验用户的ip和允许的ip是否一致
        String ipaddress = (String) map.get("ipaddress");
        boolean flag = false;
        for (String ip : ipaddress.split(",")) {
            if (!StringUtils.isEmpty(userIp)&&ip.equals(userIp)){
                flag = true;
                break;
            }
        }
        if (!flag){
            //没有匹配到
            //记录日志
            log.info("【接口模块】 IP校验错误。  userIp={}",userIp);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_IP_ERROR);
        }


        //-----------------------------------4.校验短信内容-----------------------------------
        String content = smsInterfaceForm.getContent();
        if (StringUtils.isEmpty(content)||content.length()>500){
            //记录日志
            log.info("【接口模块】 消息长度错误，为空或超长（目前定为500个字）。  content={}",content);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_CONTENT_ERROR);
        }


        //-----------------------------------5.校验手机号-----------------------------------
        String mobiles = smsInterfaceForm.getMobile();
        //非空校验
        if (StringUtils.isEmpty(mobiles)){
            //记录日志
            log.info("【接口模块】 手机号错误。  content={}",content);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_MOBILE_ERROR);
        }

        String[] mobileArray = mobiles.split(",");
        //手机号个数校验
        if (mobileArray.length==0||mobileArray.length>100){
            //记录日志
            log.info("【接口模块】 手机号错误。  content={}",content);
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_MOBILE_ERROR);
        }

        //手机号格式校验
        String regex = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";
        //有问题手机号的set集合
        Set<String> mobileSet = new HashSet();
        for (String mobile : mobileArray) {
            if (!mobile.matches(regex)){
                mobileSet.add(mobile);
            }
        }

        //有错误的手机号
        if (mobileSet.size()>0){
            //记录日志
            log.info("【接口模块】 手机号错误。  mobileArray={}", Arrays.toString(mobileArray));
            //抛出异常
            throw new SmsException(InterfaceExceptionEnums.INTERFACE_MOBILE_ERROR,mobileSet);
        }




        //-----------------------------------6.校验下行编号-----------------------------------
        String srcIDStr = smsInterfaceForm.getSrcID();
        if (!StringUtils.isEmpty(srcIDStr)){
            try {
                Long srcID = Long.parseLong(srcIDStr);
            } catch (NumberFormatException e) {
                //记录日志
                log.info("【接口模块】 下行编号（srcID）错误。  srcIDStr={}", srcIDStr);
                //抛出异常
                throw new SmsException(InterfaceExceptionEnums.INTERFACE_SRC_ID_ERROR);
            }
        }


        //-----------------------------------7.校验通过，发消息到RabbitMQ-----------------------------------
        for (String mobile : mobileArray) {
            //封装消息对象
            StandardSubmit standardSubmit = new StandardSubmit();

            //当前对象的唯一标识
            standardSubmit.setSequenceId(String.valueOf(idWorkerNum.nextId()));
            //客户端ID
            standardSubmit.setClientID(Integer.valueOf(smsInterfaceForm.getClientID()));
            //消息的优先级 0 最低 --- 3 最高
            standardSubmit.setMessagePriority(Short.parseShort((String) map.get("priority")));
            //客户侧唯一序列号srcID
            standardSubmit.setSrcSequenceId(Long.valueOf(smsInterfaceForm.getSrcID()));
            //目的手机号
            standardSubmit.setDestMobile(mobile);
            //短信内容
            standardSubmit.setMessageContent(smsInterfaceForm.getContent());
            //手机接收的状态值  0 成功 1 等待 2 失败
            standardSubmit.setReportState(ReportStateConstants.WAIT);
            //短信发送时间
            standardSubmit.setSendTime(new Date());
            //发送方式 1 HTTP 2 WEB
            standardSubmit.setSource(SourceType.HTTP);

            //发送消息
            rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND+"_exchange","routingKey", standardSubmit);
        }

    }
}
